package framework.states;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.Socket;

import org.newdawn.slick.GameContainer;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.state.StateBasedGame;

import framework.BasicFighter;
import framework.Controls;
import framework.Stage;

public class OnlineFight extends Fight {

	public static final int ID = 3;
	/** Socket used to send inputs */
	private Socket comSocket;
	/** */
	private PrintWriter out;
	/** */
	private BufferedReader in;
	/** */
	private BasicFighter activeFighter;
	/** */
	private BasicFighter remoteFighter;

	public OnlineFight(BasicFighter fighter1, BasicFighter fighter2, Stage stage) {
		super(fighter1, fighter2, stage);
	}

	@Override
	public int getID() {
		return ID;
	}

	public Socket getCommunicationSocket() {
		return comSocket;
	}

	/**
	 * 1 for first player
	 * 2 for second player
	 * @param player
	 */
	public void setActivePlayer(int player) {
		if (player == 1) {
			activeFighter = fighter1;
			remoteFighter = fighter2;
		} else {
			activeFighter = fighter2;
			remoteFighter = fighter1;
		}
	}
	
	public void setCommunicationSocket(Socket comSocket) {
		this.comSocket = comSocket;
		if (comSocket != null) {
			try {
				this.out = new PrintWriter(comSocket.getOutputStream(), true);
				this.in = new BufferedReader(
						new InputStreamReader(comSocket.getInputStream()));
				receiveInput();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public void sendInput(String input) {
		if (out != null) {
			out.println(input);
			System.out.println("Sending input : " + input);
		} else {
			System.out.println("meh send");
		}
	}

	public void receiveInput() {
		System.out.println("Establishing the thread for receiving inputs.");
		(new Thread() {
			@Override
			public void run() {
				while (true)  {
					if (in != null) {
						try {
							String receive;
							receive = in.readLine();
							System.out.println("Waitin...");
							System.out.println("Received : " + receive);
							String[] split = receive.split("#");
							if (split[1].equals("r")) {
								performReleasedAction(Controls.getControls(split[0]), remoteFighter);
							} else {
							    performAction(Controls.getControls(split[0]), false);
							}
						} catch (IOException e) {
							e.printStackTrace();
						}
					} else {
						System.out.println("?");
					}
				}
			}
		}).start();
	}

	@Override
	public void update(GameContainer gc, StateBasedGame game, int ms)
			throws SlickException {
		super.update(gc, game, ms);	
	}

	@Override
	public void manageInput(int controller, String button, boolean released) {
		Controls c = this.caller.getAction(controller, button);
		String strReleased = released ? "#r" : "#nr";
		// for local debugging
		if (c == null || Controls.getPlayer(c) == 2) {
			return;
		}
		sendInput(c.toString() + strReleased);
		if (released) {
			super.performReleasedAction(c, this.activeFighter);
		} else {
			super.performAction(c, false);
		}
	}

	@Override
	protected void performAction(Controls c, boolean buffer) {
		System.out.println("Action performed at " + timer);
		super.performAction(c, buffer);
	}

	@Override
	protected void performReleasedAction(Controls c, BasicFighter fighter) {
		System.out.println("Action performed at " + timer);
		super.performReleasedAction(c, fighter);
	}
	
	
}
